package com.rybbaby.tss.core.code.generate.config;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import com.rybbaby.tss.core.bean.ForeignKeyBean;
import com.rybbaby.tss.core.utils.PropertiesReadUtil;

public class GenerateConfig {
	
	/** 默认工程绝对路径 **/
	public static String DEFAULTPROJECTDIR;
	/** 默认需要生成的模板名称,用逗号隔开 **/
	public static String DEFAULTTEMPLATESMAPPING;
	/** 默认模块名称 **/
	public static String DEFAULTMODULE;
	/** 默认模板位置(相对月project.dir值) **/
	public static String DEFAULTTEMPLATEDIR;
	/** 默认java文件输出目录(相对月project.dir值) **/
	public static String DEFAULTJAVAFILEOUTDIR;
	/** 默认视图文件目录(相对月project.dir值) **/
	public static String DEFAULTVIEWFILEOUTDIR;
	/** 默认开发者姓名 **/
	public static String DEFAULTAUTHOR;
	/** 数据库连接驱动 **/
	public static String DEFAULTJDBCDRIVER;
	/** 默认数据源连接地址 **/
	public static String DEFAULTJDBCURL;
	/** 默认数据源连接用户名 **/
	public static String DEFAULTJDBCUSERNAME;
	/** 默认数据源连接密码 **/
	public static String DEFAULTJDBCPASSWORD;
	
	static {
		// 读取默认值
		DEFAULTPROJECTDIR = PropertiesReadUtil.getStringProperty("project.dir");
		DEFAULTTEMPLATESMAPPING = PropertiesReadUtil.getStringProperty("template.default.templates.mapping");
		DEFAULTMODULE = PropertiesReadUtil.getStringProperty("template.default.module");
		DEFAULTTEMPLATEDIR = PropertiesReadUtil.getStringProperty("template.default.template.dir");
		DEFAULTJAVAFILEOUTDIR = PropertiesReadUtil.getStringProperty("template.default.java.file.out.dir");
		DEFAULTVIEWFILEOUTDIR = PropertiesReadUtil.getStringProperty("template.default.view.file.out.dir");
		DEFAULTAUTHOR = PropertiesReadUtil.getStringProperty("template.default.author");
		DEFAULTJDBCDRIVER = PropertiesReadUtil.getStringProperty("template.default.jdbc.driver");
		DEFAULTJDBCURL = PropertiesReadUtil.getStringProperty("template.default.jdbc.url");
		DEFAULTJDBCUSERNAME = PropertiesReadUtil.getStringProperty("template.default.jdbc.userName");
		DEFAULTJDBCPASSWORD = PropertiesReadUtil.getStringProperty("template.default.jdbc.password");
	}
	
	/** 开发者姓名 **/
	private String author;
	/** 工程绝对路径 **/
	private String projectDir;
	/** 需要生成的模板名称,用逗号隔开 **/
	private String templatesMapping;
	/** 模块名称 **/
	private String module;
	/** 模板位置(相对月project.dir值) **/
	private String templateDir;
	/** java文件输出目录(相对月project.dir值) **/
	private String javaFileOutDir;
	/** 视图文件目录(相对月project.dir值) **/
	private String viewFileOutDir;
	/** 数据库连接驱动 **/
	private String jdbcDriver;
	/** 数据源连接地址 **/
	private String jdbcUrl;
	/** 数据源连接用户名 **/
	private String jdbcUserName;
	/** 数据源连接密码 **/
	private String jdbcPassword;
	
	/** 参照catalog **/
	private String catalog;
	/** 参考表表名 **/
	private String tableName;
	/** 实体类名 **/
	private String entityName;
	/** 数据库字段属性参数json串映射(key为表名,value为属性参数json字符串) **/
	private Map<String , String> attrJsonConfigStrs;
	/** 生成文件映射(key为表名,value的key为各个模板配置的后缀，value为属性参数是否生成文件) **/
	private Map<String , Map<String , Boolean>> genFielsMaps;
	/** 多表生成时的业务描述映射(key为表名,value为属性参数描述字符串) **/
	private Map<String , String> businessDescriptionMaps;
	/** 删除标识字段映射(key为表名,value为删除标识属性字段) **/
	private Map<String , String> logicDeleteMaps;
	/** 业务描述名称 **/
	private String businessDescription;
	/** 外键 **/
	private List<ForeignKeyBean> foreignKeys = new ArrayList<ForeignKeyBean>();
	
	public GenerateConfig (){
		super();
	}
	
	/**
	 * @param projectDir
	 *            工程绝对路径
	 * @param templatesMapping
	 *            需要生成的模板名称,用逗号隔开
	 * @param module
	 *            模块名称
	 * @param templateDir
	 *            模板位置(相对月project.dir值)
	 * @param javaFileOutDir
	 *            java文件输出目录(相对月project.dir值)
	 * @param viewFileOutDir
	 *            视图文件目录(相对月project.dir值)
	 * @param jdbcDriver
	 *            数据库连接驱动
	 * @param jdbcUrl
	 *            数据库连接地址
	 * @param jdbcUserName
	 *            数据源连接用户名
	 * @param jdbcPassword
	 *            数据源连接密码
	 * @param businessDescription
	 *            业务描述
	 * @param author
	 *            开发者姓名
	 */
	public GenerateConfig (String projectDir , String templatesMapping , String module , String templateDir , String javaFileOutDir , String viewFileOutDir , String jdbcDriver , String jdbcUrl , String jdbcUserName , String jdbcPassword , String author ){
		this(projectDir , templatesMapping , module , templateDir , javaFileOutDir , viewFileOutDir , author);
		this.jdbcDriver = jdbcDriver;
		this.jdbcUrl = jdbcUrl;
		this.jdbcUserName = jdbcUserName;
		this.jdbcPassword = jdbcPassword;
	}
	
	/**
	 * @param projectDir
	 *            工程绝对路径
	 * @param templatesMapping
	 *            需要生成的模板名称,用逗号隔开
	 * @param module
	 *            模块名称
	 * @param templateDir
	 *            模板位置(相对月project.dir值)
	 * @param javaFileOutDir
	 *            java文件输出目录(相对月project.dir值)
	 * @param viewFileOutDir
	 *            视图文件目录(相对月project.dir值)
	 */
	public GenerateConfig (String projectDir , String templatesMapping , String module , String templateDir , String javaFileOutDir , String viewFileOutDir , String author ){
		this();
		this.projectDir = projectDir;
		this.templatesMapping = templatesMapping;
		this.module = module;
		this.templateDir = templateDir;
		this.javaFileOutDir = javaFileOutDir;
		this.viewFileOutDir = viewFileOutDir;
		this.author = author;
	}
	
	public String getAuthor() {
		if(StringUtils.isNotBlank(this.author)) {
			return this.author;
		} else {
			return DEFAULTAUTHOR;
		}
	}
	
	public void setAuthor(String author) {
		this.author = author;
	}
	
	/**
	 * 工程所在实际目录
	 * 
	 * @return
	 */
	public String getProjectDir() {
		if(StringUtils.isNotBlank(this.projectDir)) {
			return this.projectDir;
		} else {
			return DEFAULTPROJECTDIR;
		}
	}
	
	/**
	 * 设置工程所在实际目录
	 * 
	 * @param projectDir
	 */
	public void setProjectDir(String projectDir) {
		this.projectDir = projectDir;
	}
	
	/**
	 * 获取模板映射规则
	 * 
	 * @return
	 */
	public String getTemplatesMapping() {
		if(StringUtils.isNotBlank(this.templatesMapping)) {
			return this.templatesMapping;
		} else {
			return DEFAULTTEMPLATESMAPPING;
		}
	}
	
	/**
	 * 设置模板映射规则
	 * 
	 * @param templatesMapping
	 */
	public void setTemplatesMapping(String templatesMapping) {
		this.templatesMapping = templatesMapping;
	}
	
	/**
	 * 设置功能模块
	 * 
	 * @return
	 */
	public String getModule() {
		if(StringUtils.isNotBlank(this.module)) {
			return this.module;
		} else {
			return DEFAULTMODULE;
		}
	}
	
	/**
	 * 设置功能模块
	 * 
	 * @param module
	 */
	public void setModule(String module) {
		this.module = module;
	}
	
	/**
	 * 模板文件所在目录
	 * 
	 * @return
	 */
	public String getTemplateDir() {
		if(StringUtils.isNotBlank(this.templateDir)) {
			return this.getProjectDir() + File.separator + this.templateDir;
		} else {
			return this.getProjectDir() + File.separator + DEFAULTTEMPLATEDIR;
		}
	}
	
	/**
	 * 模板文件相对工程所在目录
	 * 
	 * @return
	 */
	public String getRelativeTemplateDir() {
		if(StringUtils.isNotBlank(this.templateDir)) {
			return File.separator + this.templateDir;
		} else {
			return File.separator + DEFAULTTEMPLATEDIR;
		}
	}
	
	/**
	 * 设置模板文件所在目录
	 * 
	 * @param templateDir
	 */
	public void setTemplateDir(String templateDir) {
		this.templateDir = templateDir;
	}
	
	/**
	 * 生成Java文件存放目录
	 * 
	 * @return
	 */
	public String getJavaFileOutDir() {
		if(StringUtils.isNotBlank(this.javaFileOutDir)) {
			return this.getProjectDir() + File.separator + this.javaFileOutDir;
		} else {
			return this.getProjectDir() + File.separator + DEFAULTJAVAFILEOUTDIR;
		}
	}
	
	/**
	 * 生成Java文件相对工程存放目录
	 * 
	 * @return
	 */
	public String getRelativeJavaFileOutDir() {
		if(StringUtils.isNotBlank(this.javaFileOutDir)) {
			return File.separator + this.javaFileOutDir;
		} else {
			return File.separator + DEFAULTJAVAFILEOUTDIR;
		}
	}
	
	/**
	 * 设置Java文件存放目录
	 * 
	 * @param viewFileOutDir
	 */
	public void setJavaFileOutDir(String javaFileOutDir) {
		this.javaFileOutDir = javaFileOutDir;
	}
	
	/**
	 * 生成视图文件存放目录
	 * 
	 * @return
	 */
	public String getViewFileOutDir() {
		if(StringUtils.isNotBlank(this.viewFileOutDir)) {
			return this.getProjectDir() + File.separator + this.viewFileOutDir;
		} else {
			return this.getProjectDir() + File.separator + DEFAULTVIEWFILEOUTDIR;
		}
	}
	
	/**
	 * 生成视图文件相对工程的存放目录
	 * 
	 * @return
	 */
	public String getRelativeViewFileOutDir() {
		if(StringUtils.isNotBlank(this.viewFileOutDir)) {
			return File.separator + this.viewFileOutDir;
		} else {
			return File.separator + DEFAULTVIEWFILEOUTDIR;
		}
	}
	
	/**
	 * 设置视图文件存放目录
	 * 
	 * @param viewFileOutDir
	 */
	public void setViewFileOutDir(String viewFileOutDir) {
		this.viewFileOutDir = viewFileOutDir;
	}
	
	/**
	 * @return 数据库连接驱动
	 */
	public String getJdbcDriver() {
		if(StringUtils.isNotBlank(this.jdbcDriver)) {
			return this.jdbcDriver;
		} else {
			return DEFAULTJDBCDRIVER;
		}
	}
	
	/**
	 * @param jdbcDriver
	 *            数据库连接驱动
	 */
	public void setJdbcDriver(String jdbcDriver) {
		this.jdbcDriver = jdbcDriver;
	}
	
	/**
	 * @return 设置上数据库链接地址
	 */
	public String getJdbcUrl() {
		if(StringUtils.isNotBlank(this.jdbcUrl)) {
			return this.jdbcUrl;
		} else {
			return DEFAULTJDBCURL;
		}
	}
	
	/**
	 * @param 设置上数据库链接地址
	 */
	public void setJdbcUrl(String jdbcUrl) {
		this.jdbcUrl = jdbcUrl;
	}
	
	/**
	 * @return 数据库连接用户名
	 */
	public String getJdbcUserName() {
		if(StringUtils.isNotBlank(this.jdbcUserName)) {
			return this.jdbcUserName;
		} else {
			return DEFAULTJDBCUSERNAME;
		}
	}
	
	/**
	 * @param jdbcUserName
	 *            设置连接用户名
	 */
	public void setJdbcUserName(String jdbcUserName) {
		this.jdbcUserName = jdbcUserName;
	}
	
	/**
	 * @return 数据库连接密码
	 */
	public String getJdbcPassword() {
		if(StringUtils.isNotBlank(this.jdbcPassword)) {
			return this.jdbcPassword;
		} else {
			return DEFAULTJDBCPASSWORD;
		}
	}
	
	/**
	 * @param jdbcPassword
	 *            数据库连接密码
	 * 
	 */
	public void setJdbcPassword(String jdbcPassword) {
		this.jdbcPassword = jdbcPassword;
	}
	
	public String getCatalog() {
		return catalog;
	}
	
	public void setCatalog(String catalog) {
		this.catalog = catalog;
	}
	
	public String getEntityName() {
		return entityName;
	}
	
	public void setEntityName(String entityName) {
		this.entityName = entityName;
	}
	
	public String getTableName() {
		return tableName;
	}
	
	public void setTableName(String tableName) {
		this.tableName = tableName;
	}
	
	public Map<String , String> getAttrJsonConfigStrs() {
		return attrJsonConfigStrs;
	}
	
	public void setAttrJsonConfigStrs(Map<String , String> attrJsonConfigStr) {
		this.attrJsonConfigStrs = attrJsonConfigStr;
		setAttrJsonConfig();
	}
	
	/** 表的字段属性参数 **/
	private Map<String , Map<String , Map<String , Object>>> attrJsonConfig = new HashMap<String , Map<String , Map<String , Object>>>();
	
	public Map<String , Map<String , Object>> getAttrJsonConfig(String tableName) {
		return this.attrJsonConfig.get(tableName);
	}
	
	private void setAttrJsonConfig() {
		if(this.attrJsonConfigStrs != null && !this.attrJsonConfigStrs.isEmpty()) {
			Set<String> tables = this.attrJsonConfigStrs.keySet();
			for(String table : tables) {
				String fieldConfigJsonStr = this.attrJsonConfigStrs.get(table);
				JSONObject fieldConfigJson = JSONObject.fromObject(fieldConfigJsonStr.replaceAll("\\r\n" , ""));
				if(fieldConfigJson == null || fieldConfigJson.isEmpty()) {
					continue;
				}
				Map<String , Map<String , Object>> fieldMap = new HashMap<String , Map<String , Object>>();
				Iterator<?> fields = fieldConfigJson.keys();
				while (fields.hasNext()) {
					String field = fields.next().toString();
					Object configJsonObj = fieldConfigJson.get(field);
					if(configJsonObj != null && !"".equals(configJsonObj)) {
						Map<String , Object> map = new HashMap<String , Object>();
						JSONObject configs = JSONObject.fromObject(configJsonObj);
						Iterator<?> keys = configs.keys();
						while (keys.hasNext()) {
							String attrName = keys.next().toString();
							Object attrValue = configs.get(attrName);
							attrName = attrName.equals("_class") ? attrName.toString().replace("_" , "") : attrName;
							if(attrValue != null && !"".equals(attrValue) && !"null".equals(attrValue + "")) {
								map.put(attrName , attrValue);
							}
						}
						fieldMap.put(field , map);
					}
				}
				this.attrJsonConfig.put(table , fieldMap);
			}
		}
	}
	
	public Map<String , Map<String , Boolean>> getGenFielsMaps() {
		return genFielsMaps;
	}
	
	public void setGenFielsMaps(Map<String , Map<String , Boolean>> genFielsMaps) {
		this.genFielsMaps = genFielsMaps;
	}
	
	public String getBusinessDescription() {
		return businessDescription;
	}
	
	public void setBusinessDescription(String businessDescription) {
		this.businessDescription = businessDescription;
	}
	
	public Map<String , String> getBusinessDescriptionMaps() {
		return businessDescriptionMaps;
	}
	
	public void setBusinessDescriptionMaps(Map<String , String> businessDescriptionMaps) {
		this.businessDescriptionMaps = businessDescriptionMaps;
	}
	
	public Map<String , String> getLogicDeleteMaps() {
		return logicDeleteMaps;
	}
	
	public void setLogicDeleteMaps(Map<String , String> logicDeleteMaps) {
		this.logicDeleteMaps = logicDeleteMaps;
	}
	
	public List<ForeignKeyBean> getForeignKeys() {
		return foreignKeys;
	}
	
	public void setForeignKeys(List<ForeignKeyBean> foreignKeys) {
		this.foreignKeys = foreignKeys;
	}
	
	@Override
	public String toString() {
		return "GenerateConfig [projectDir=" + projectDir + ", templatesMapping=" + templatesMapping + ", module=" + module + ", templateDir=" + templateDir + ", javaFileOutDir=" + javaFileOutDir + ", viewFileOutDir=" + viewFileOutDir + ", jdbcDriver=" + jdbcDriver + ", jdbcUrl=" + jdbcUrl + ", jdbcUserName=" + jdbcUserName + ", jdbcPassword=" + jdbcPassword + ", catalog=" + catalog + ", tableName=" + tableName + ", attrJsonConfigStr=" + attrJsonConfigStrs + "]";
	}
}
